
import cors from '@fastify/cors';
import fastifySwagger from '@fastify/swagger';
import fastifySwaggerUi from '@fastify/swagger-ui';
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
import Fastify from 'fastify';
import { fastifyTRPCOpenApiPlugin, generateOpenApiDocument } from 'trpc-openapi';
import { appRouter } from './Routes/AppRouter';
import { createReadStream } from 'fs';
import { resolve } from 'path';
import { createContext } from './context';

const app = Fastify();

async function main() {
    // Setup CORS
    await app.register(cors);

    // Handle incoming tRPC requests
    await app.register(fastifyTRPCPlugin, {
        prefix: '/trpc',
        useWss: false,
        trpcOptions: {
            router: appRouter,
            createContext
        },
    } as any);

    // Handle incoming OpenAPI requests
    await app.register(fastifyTRPCOpenApiPlugin, {
        basePath: '/api',
        router: appRouter,
        createContext,
    });

    //生成OpenApi文档
    const openApiDocument = generateOpenApiDocument(appRouter, {
        title: 'tRPC OpenAPI',
        version: '1.0.0',
        baseUrl: 'http://localhost:3000/api',
        securitySchemes: {
            //ref:https://github.com/rapi-doc/RapiDoc/issues/553
            Authorization: {
                type: 'apiKey',
                name: 'Authorization',
                in: "header"
            },
        }
    });

    //启动Swagger服务 Serve the OpenAPI document
    await app.register(fastifySwagger, {
        prefix: '/docs2',
        mode: 'static',
        specification: { document: openApiDocument },
    });

    await app.register(fastifySwaggerUi, {
        routePrefix: '/docs2',
        uiConfig: { displayOperationId: true },
    });

    //启动 RapiDoc 服务
    app.get("/docs", (req, res) => {
        const stream = createReadStream(resolve('./src/doc.html'))
        res.type('text/html').send(stream)
    })
    app.get("/api.json", (req, res) => {
        return openApiDocument
    })

    let address = await app.listen({ host: "::", port: 3000 })
    app.swagger();
    console.log(`服务: ${address}\n文档: ${address}/docs`);
}

main().catch((err) => {
    console.error("启动失败:" + err);
    process.exit(1);
});

//pm2关闭进程前，会发出SIGINT信号，我们的程序接收到此信号，开始进行优雅下线
process.on("SIGINT", () => {
    app.server.keepAliveTimeout = 1;
    console.log("开始安全退出...");
    // 调用close方法会处理完目前已有的链接
    app.close(() => {
        // 执行到这里，说明当前进程中的请求处理完毕，退出进程
        console.log("安全退出成功!");
        process.exit(0);
    });
});
